﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using NUnit.Framework;
using SJTU.SE.RoughSet.Lib.Data;
using SJTU.SE.RoughSet.Lib.IO;
using SJTU.SE.RoughSet.Lib.Reduct;

namespace SJTU.SE.RoughSet.Test.Reduct
{
    [TestFixture]
    class ReductorTest
    {
        Reductor testReductor = new Reductor(new DecisionTable(new DecisionTableFileInitializer(".\\TestData\\zoo.txt")));

        [Test]
        public void Reductor_constructor_should_init_correctly()
        {
            Assert.AreEqual(1, testReductor.TargetDecisionTable[0, 0]);
            Assert.AreEqual(0, testReductor.TargetDecisionTable[1, 2]);
        }

        [Test]
        public void Reductor_should_return_right_SkowronCore()
        {
            List<int> skowronCore = testReductor.GetSkowronCore();

            Assert.IsNotNull(skowronCore);
            Assert.AreEqual(2, skowronCore.Count);
            Assert.Contains(5, skowronCore);
            Assert.Contains(12, skowronCore);
            
        }

        [Test]
        [ExpectedException(ExpectedMessage = "Inconsistent decision table")]
        public void Reductor_SkowronCore_should_throw_right_exception_with_inconsistent_decision_table()
        {
            Reductor testReductorException = new Reductor(new DecisionTable(new IO.DecisionTableMockInitializer()));
            var temp = testReductorException.GetSkowronCore();
        }

        [Test]
        public void Reductor_IsReduction_should_return_true_for_reduction()
        {
            List<int> reductionTrue = new List<int>();//2,5,8,12,15
            reductionTrue.Add(2);
            reductionTrue.Add(5);
            reductionTrue.Add(8);
            reductionTrue.Add(12);
            reductionTrue.Add(15);

            Assert.AreEqual(true, testReductor.IsReduction(reductionTrue));

            List<int> reductionTrue2 = new List<int>();
            reductionTrue2.Add(2);
            reductionTrue2.Add(5);
            reductionTrue2.Add(6);
            reductionTrue2.Add(9);
            reductionTrue2.Add(11);
            reductionTrue2.Add(12);
            reductionTrue2.Add(15);

            Assert.AreEqual(true, testReductor.IsReduction(reductionTrue2));

        }

        [Test]
        public void Reductor_IsReduction_should_return_false_for_no_reduction()
        {
            List<int> reductionMore = new List<int>();//2,5,8,12,15
            reductionMore.Add(2);
            reductionMore.Add(5);
            reductionMore.Add(8);
            reductionMore.Add(12);
            reductionMore.Add(14);//add one
            reductionMore.Add(15);

           //TODO Assert.AreEqual(false, testReductor.IsReduction(reductionMore), "Add a external attribute");

            List<int> reductionLess = new List<int>();
            reductionLess.Add(2);
            reductionLess.Add(5);
            reductionLess.Add(6);
            reductionLess.Add(9);
            reductionLess.Add(11);
            reductionLess.Add(12);
            //reductionTrue2.Add(15); //minus one

            Assert.AreEqual(false, testReductor.IsReduction(reductionLess), "minus one");

            List<int> reductionFalse = new List<int>();
            reductionFalse.Add(2);
            reductionFalse.Add(8);
            reductionFalse.Add(12);
            reductionFalse.Add(15);
            Assert.AreEqual(false, testReductor.IsReduction(reductionFalse),"2,8,12,5");
        }

        [Test]
        public void Reductor_GetAllReductions_should_return_right_reductions()
        {
            var reductions = testReductor.GetAllReductionsByTraversal();

            Assert.AreEqual(33, reductions.Count);
        }

        //[Test]
        //public void Reductor_GetAllReductionsByIndiscernibilityFunction_should_return_right_reductions()
        //{
        //    var reductions = testReductor.GetAllReductionByIndiscernibilityFunction();

        //    Assert.AreEqual(33, reductions.Count);
        //}
    }
}
